﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KinectDwa;
using System.ComponentModel;
using System.Drawing;
using System.Diagnostics;
using System.Runtime.Serialization;
using System.IO;
using KinectDwa.Parsers;
using System.Windows;
using System.Media;


namespace Kinect.Tests
{

    [DataContract]
    public enum CalculatorTestMode
    {
        [Description("1")]
        [EnumMember]
        Press1a,
        [Description("1")]
        [EnumMember]
        Press1b,
        [Description("1")]
        [EnumMember]
        Press1c,
        [Description("2")]
        [EnumMember]
        Press2a,
        [Description("2")]
        [EnumMember]
        Press2b,
        [Description("2")]
        [EnumMember]
        Press2c,
        [Description("3")]
        [EnumMember]
        Press3a,
        [Description("3")]
        [EnumMember]
        Press3b,
        [Description("3")]
        [EnumMember]
        Press3c,
        [Description("4")]
        [EnumMember]
        Press4a,
        [Description("4")]
        [EnumMember]
        Press4b,
        [Description("4")]
        [EnumMember]
        Press4c,
        [Description("5")]
        [EnumMember]
        Press5a,
        [Description("5")]
        [EnumMember]
        Press5b,
        [Description("5")]
        [EnumMember]
        Press5c,
        [Description("6")]
        [EnumMember]
        Press6a,
        [Description("6")]
        [EnumMember]
        Press6b,
        [Description("6")]
        [EnumMember]
        Press6c,
        [Description("7")]
        [EnumMember]
        Press7a,
        [Description("7")]
        [EnumMember]
        Press7b,
        [Description("7")]
        [EnumMember]
        Press7c,
        [Description("8")]
        [EnumMember]
        Press8a,
        [Description("8")]
        [EnumMember]
        Press8b,
        [Description("8")]
        [EnumMember]
        Press8c,
        [Description("9")]
        [EnumMember]
        Press9a,
        [Description("9")]
        [EnumMember]
        Press9b,
        [Description("9")]
        [EnumMember]
        Press9c

    

        /*
        [Description("4")]
        [EnumMember]
        OnePlusThree,
        [Description("30")]
        [EnumMember]
        FiveTimesSix,
        [Description("2")]
        [EnumMember]
        SixDividedByThree,
        [Description("111")]
        [EnumMember]
        EightHundredAndEightyEightMinusSevenHundredAndSeventySeven,
        [Description("24")]
        [EnumMember]
        NinePlusEightPlusSeven
        */

        /*
        [Description("4")]
        OnePlusThree,
        [Description("36")]
        SixTimesSix,
        [Description("50000")]
        FiveHundredDividedByZeroPointZeroOne,
        [Description("111")]
        EightHundredAndEightyEightMinusSevenHundredAndSeventySeven,
        [Description("10")]
        NinePlusEightPlusSevenDividedByTwoPointFour
         */
    }

    [DataContract]
    public enum CalculatorSymbol
    {
        [Description("")]
        None,
        [Description("1")]
        One,
        [Description("2")]
        Two,
        [Description("3")]
        Three,
        [Description("4")]
        Four,
        [Description("5")]
        Five,
        [Description("6")]
        Six,
        [Description("7")]
        Seven,
        [Description("8")]
        Eight,
        [Description("9")]
        Nine,
        [Description("0")]
        Zero,
        [Description("+")]
        Add,
        [Description("-")]
        Substract,
        [Description("*")]
        Multiply,
        [Description("/")]
        Divide,
        [Description(".")]
        Decimal,
        [Description("Ok")]
        Ok
    }

    [DataContract]
    public class TestInfo
    {
        [DataMember]
        public TimeSpan Elapsed;
        [DataMember]
        public List<ClickInfo> Clicks = new List<ClickInfo>();
        [DataMember]
        public ClickInfo OkClick;
        [DataMember]
        public TestMode TestType;
        [DataMember]
        public int FalseClicks;
        [DataMember]
        public List<CalculatorTestMode> SuccessfulAnswers = new List<CalculatorTestMode>();

        public TestInfo(TestMode mode)
        {
            TestType = mode;
        }

        public override string ToString()
        {
            return String.Format("Test: {0}{3} Time: {1}{3} Fails: {2}{3}", TestType.ToString(), Elapsed.ToString(), FalseClicks, Environment.NewLine);
        }
    }

    [DataContract]
    public class ClickInfo
    {
        [DataMember]
        public int X;
        [DataMember]
        public int Y;
        [DataMember]
        public bool Hit;
        [DataMember]
        public bool RightButton;
        [DataMember]
        public TimeSpan Elapsed;
        [DataMember]
        public string ClickedButton;
        [DataMember]
        public string CorrectButton;

        public ClickInfo(System.Drawing.Point point, bool hit, TimeSpan elapsed, string correctButton, string clickedButton)
        {
            X = point.X;
            Y = point.Y;
            Hit = hit;
            Elapsed = elapsed;
            RightButton = correctButton == clickedButton;
            CorrectButton = correctButton;
            ClickedButton = clickedButton;
        }
    }


    public static class StaticTestEngine
    {

        public static SoundPlayer ClickSound = new SoundPlayer(@"c:\Windows\Media\Windows Navigation Start.wav");
    

        private static Random random = new Random();

        private static TestInfo ActiveTest;
        public static TestMode ActiveTestType;
        public static CalculatorTestMode CalculatorMode;

        private static List<TestMode> AvailableTests = new List<TestMode>();
        private static List<TestInfo> Tests = new List<TestInfo>();
        private static List<CalculatorTestMode> AvailableCalculations = new List<CalculatorTestMode>();
        private static List<CalculatorSymbol> CorrectButtons = new List<CalculatorSymbol>();

        public static bool Sticky = false;

        private static Stopwatch timer = new Stopwatch();


        public static int TestCounter = 0;
        public static int NumberOfTests = 0;

        public static void StartTesting()
        {
            AvailableTests = Enum.GetValues(typeof(TestMode)).Cast<int>().OrderBy(x => random.Next()).Cast<TestMode>().ToList();
            AvailableTests.Remove(TestMode.MouseThing);
            AvailableTests.Insert(0, TestMode.MouseThing);

           // AvailableTests = new List<TestMode>();
            //AvailableTests.Add(TestMode.PushButton);
            //AvailableTests.Add(TestMode.PushButton);
            //AvailableTests.Add(TestMode.TwoHandedPushButton);
            //AvailableTests.Add(TestMode.StickyPushButton);
         
            

            NumberOfTests = AvailableTests.Count;

            NextText();
        }

        //advance to next test, no recording here
        public static void NextText()
        {
            StickyButtonHandler.Focus(null);

            //next
            if (AvailableTests.Count > 0)
            {
                TestCounter++;

                // Le smooth randomization!
                //AvailableCalculations = Enum.GetValues(typeof(CalculatorTestMode)).Cast<int>().OrderBy(x => random.Next()).Cast<CalculatorTestMode>().ToList();

                // Le crude partial randomization
                AvailableCalculations = new List<CalculatorTestMode>();
                IEnumerable<int> semirandom1 = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.OrderBy(x => random.Next()).Take(6);

                IEnumerable<int> semirandom2 = new int[] { 10, 11, 12, 13, 14, 15, 16, 17, 18 }.OrderBy(x => random.Next()).Take(6);

                foreach (int derp in semirandom1.Concat(semirandom2))
                {
                    switch (derp)
                    {
                        case 1:
                            AvailableCalculations.Add(CalculatorTestMode.Press1a);
                            break;
                        case 2:
                            AvailableCalculations.Add(CalculatorTestMode.Press2a);
                            break;
                        case 3:
                            AvailableCalculations.Add(CalculatorTestMode.Press3a);
                            break;
                        case 4:
                            AvailableCalculations.Add(CalculatorTestMode.Press4a);
                            break;
                        case 5:
                            AvailableCalculations.Add(CalculatorTestMode.Press5a);
                            break;
                        case 6:
                            AvailableCalculations.Add(CalculatorTestMode.Press6a);
                            break;
                        case 7:
                            AvailableCalculations.Add(CalculatorTestMode.Press7a);
                            break;
                        case 8:
                            AvailableCalculations.Add(CalculatorTestMode.Press8a);
                            break;
                        case 9:
                            AvailableCalculations.Add(CalculatorTestMode.Press9a);
                            break;

                        case 10:
                            AvailableCalculations.Add(CalculatorTestMode.Press1b);
                            AvailableCalculations.Add(CalculatorTestMode.Press1c);
                            break;
                        case 11:
                            AvailableCalculations.Add(CalculatorTestMode.Press2b);
                            AvailableCalculations.Add(CalculatorTestMode.Press2c);
                            break;
                        case 12:
                            AvailableCalculations.Add(CalculatorTestMode.Press3b);
                            AvailableCalculations.Add(CalculatorTestMode.Press3c);
                            break;
                        case 13:
                            AvailableCalculations.Add(CalculatorTestMode.Press4b);
                            AvailableCalculations.Add(CalculatorTestMode.Press4c);
                            break;
                        case 14:
                            AvailableCalculations.Add(CalculatorTestMode.Press5b);
                            AvailableCalculations.Add(CalculatorTestMode.Press5c);
                            break;
                        case 15:
                            AvailableCalculations.Add(CalculatorTestMode.Press6b);
                            AvailableCalculations.Add(CalculatorTestMode.Press6c);
                            break;
                        case 16:
                            AvailableCalculations.Add(CalculatorTestMode.Press7b);
                            AvailableCalculations.Add(CalculatorTestMode.Press7c);
                            break;
                        case 17:
                            AvailableCalculations.Add(CalculatorTestMode.Press8b);
                            AvailableCalculations.Add(CalculatorTestMode.Press8c);
                            break;
                        case 18:
                            AvailableCalculations.Add(CalculatorTestMode.Press9b);
                            AvailableCalculations.Add(CalculatorTestMode.Press9c);
                            break;
                    }
                }





                ActiveTestType = AvailableTests[0];

                MouseInputControl.EnableMouse();

                switch (ActiveTestType)
                {
                    case TestMode.MouseThing:
                        MainWindow.Layout.Child = new ButtonTrainingView(ButtonMode.Normal);
                        MouseInputControl.SetInputType(GestureType.None, false);
                        MouseInputControl.DisableMouse();
                        Sticky = false;
                        break;
                    case TestMode.HoverButton:
                        MainWindow.Layout.Child = new ButtonTrainingView(ButtonMode.Hover);
                        MouseInputControl.SetInputType(GestureType.None, false);
                        Sticky = false;
                        break;
                    case TestMode.ConfirmHoverButton:
                        MainWindow.Layout.Child = new ButtonTrainingView(ButtonMode.ConfirmHover);
                        MouseInputControl.SetInputType(GestureType.None, false);
                        Sticky = false;
                        break;
                    case TestMode.GestureButton:
                        MainWindow.Layout.Child = new ButtonTrainingView(ButtonMode.Normal);
                        MouseInputControl.SetInputType(GestureType.HandGesture, false);
                        Sticky = false;
                        break;
                    case TestMode.PushButton:
                        MainWindow.Layout.Child = new ButtonTrainingView(ButtonMode.Normal);
                        MouseInputControl.SetInputType(GestureType.Push, false);
                        Sticky = false;
                        break;
                    case TestMode.ConfirmButton:
                        MainWindow.Layout.Child = new ButtonTrainingView(ButtonMode.Confirm);
                        MouseInputControl.SetInputType(GestureType.None, false);
                        Sticky = false;
                        break;

                    case TestMode.TwoHandedPushButton:
                        Sticky = false;
                        MainWindow.Layout.Child = new ButtonTrainingView(ButtonMode.Normal);
                        MouseInputControl.SetInputType(GestureType.Push, true);
                        break;
                    case TestMode.TwoHandedGestureButton:
                        Sticky = false;
                        MainWindow.Layout.Child = new ButtonTrainingView(ButtonMode.Normal);
                        MouseInputControl.SetInputType(GestureType.HandGesture, true);
                        break;

                    case TestMode.StickyGestureButton:
                        MainWindow.Layout.Child = new ButtonTrainingView(ButtonMode.Sticky);
                        MouseInputControl.SetInputType(GestureType.HandGesture, false);
                        Sticky = true;
                        break;
                    case TestMode.StickyPushButton:
                        MainWindow.Layout.Child = new ButtonTrainingView(ButtonMode.Sticky);
                        MouseInputControl.SetInputType(GestureType.Push, false);
                        Sticky = true;
                        break;
                    //case TestMode.TwoHandedStickyPushButton:
                    //    MainWindow.Layout.Child = new ButtonTrainingView(ButtonMode.Sticky);
                    //    MouseInputControl.SetInputType(GestureType.Push, true);
                    //    Sticky = true;
                    //    break;
                    //case TestMode.TwoHandedStickyGestureButton:
                    //    MainWindow.Layout.Child = new ButtonTrainingView(ButtonMode.Sticky);
                    //    MouseInputControl.SetInputType(GestureType.HandGesture, true);
                    //    Sticky = true;
                    //    break;
                    default:
                        break;
                }
              


                AvailableTests.RemoveAt(0);
            }
            //it was last one, stop now
            else
            {
                MainWindow.Layout.Child = new AllDone();

                StopRecording();
            }
        }

        public static string GetTestActiveTestTypeString()
        {
            switch (ActiveTestType)
            {
                case TestMode.MouseThing:
                    return "Mouse training";
                case TestMode.HoverButton:
                    return "Hover button";
                case TestMode.ConfirmHoverButton:
                    return "Confirm hover button";
                case TestMode.TwoHandedPushButton:
                    return "Two-handed - Push button ";
                case TestMode.TwoHandedGestureButton:
                    return "Two-handed - Gesture button";
                case TestMode.GestureButton:
                    return "Gesture button";
                case TestMode.PushButton:
                    return "Push button";
                case TestMode.ConfirmButton:
                    return "Confirm button";
                case TestMode.StickyPushButton:
                    return "Sticky push button";
                case TestMode.StickyGestureButton:
                    return "Sticky gesture button";
                //case TestMode.TwoHandedStickyPushButton:
                //    return "Two-handed - Sticky push button";
                //case TestMode.TwoHandedStickyGestureButton:
                //    return "Two-handed - Sticky gesture button";
                default:
                    return "Missing test type: " + ActiveTestType.ToString();
            }
        }

        public static bool? GestureImageOneHanded()
        {
            if ((ActiveTestType == TestMode.StickyGestureButton) || (ActiveTestType == TestMode.GestureButton))
            {
                return true;
            }
            else if ((ActiveTestType == TestMode.TwoHandedGestureButton) )
            {
                return true;
            }
            else
            {
                return null;
            }
        }

        public static string GetTestActiveTestInstructionsString()
        {
            // viittaa off-handiin...
            string handDescriptor = "other";

            if (MouseInputControl.handRight == true)
            {
                handDescriptor = "LEFT";
            }
            else if (MouseInputControl.handRight == false)
            {
                handDescriptor = "RIGHT";
            }

            if (ActiveTestType == TestMode.MouseThing)
            {
                return "Click the buttons with the mouse to familiarize yourself with the testing interface.";
                //return "Move the cursor over the button and then over the smaller confirmation button that appears to activate it.";
            }
            else if (ActiveTestType == TestMode.ConfirmButton)
            {
                return "1) Smaller confirmation button appears when cursor is over the button." + Environment.NewLine + Environment.NewLine +
                       "2) Move the cursor over the confirmation area titled \"ok\" to automatically click it.";
                //return "Move the cursor over the button and then over the smaller confirmation button that appears to activate it.";
            }
            else if (ActiveTestType == TestMode.ConfirmHoverButton)
            {
                return "1) Smaller confirmation button appears when cursor is over the button." + Environment.NewLine + Environment.NewLine +
                       "2) Move the cursor over the confirmation area titled \"ok\"" + Environment.NewLine + Environment.NewLine + 
                       "3) Wait for a moment to automatically click it.";
                //return "Move the cursor over the button and then hover over the smaller confirmation button that appears for a brief moment to activate it.";   
            }
            else if (ActiveTestType == TestMode.GestureButton)
            {
                return "1) Hold your hand in a relaxed fist." + Environment.NewLine + Environment.NewLine +
                       "2) Move the cursor over the button." + Environment.NewLine + Environment.NewLine +
                       "3) Perform the click-gesture by extending your thumb and index finger while facing the camera.";
                //return "Keep your hand relaxed but closed while moving the cursor over the button and then perform a gesture by briefly pointing out with your thumb and index finger to activate the button ";
            }
            else if (ActiveTestType == TestMode.HoverButton)
            {
                return "1) Move the cursor over the button." + Environment.NewLine + Environment.NewLine +
                       "2) Wait for a moment to automatically click it.";
                //return "Move the cursor over the button and hold for a moment to activate it.";   
            }
            else if (ActiveTestType == TestMode.PushButton)
            {
                return "1) Move the cursor over the button." + Environment.NewLine + Environment.NewLine +
                       "2) Perform a pushing motion towards the camera to click it.";
                //return "Move the cursor over the button and then perform a pushing motion towards the camera to activate it.";
            }
            else if (ActiveTestType == TestMode.StickyGestureButton)
            {
                return "1) Hold your hand in a relaxed fist." + Environment.NewLine + Environment.NewLine +
                       "2) Move the cursor over the button to focus at it." + Environment.NewLine + Environment.NewLine +
                       "3) Button is now focused and it can be activated from anywhere." + Environment.NewLine + Environment.NewLine +
                       "4) Perform the click-gesture by extending your thumb and index finger while facing the camera.";

               // return "Keep your hand relaxed but closed while moving the cursor across the button to focus at it and then perform a gesture by briefly pointing out with your thumb and index finger to activate the button.";
            }
            else if (ActiveTestType == TestMode.StickyPushButton)
            {
                return "1) Move the cursor over the button to focus at it." + Environment.NewLine + Environment.NewLine +
                       "2) Button is now focused and it can be activated from anywhere." + Environment.NewLine + Environment.NewLine +
                       "3) Perform a pushing motion towards the camera to click it.";
                //return "Move the cursor across the button to focus at it and then perform a pushing motion towards the camera to activate it.";
            }
            else if (ActiveTestType == TestMode.TwoHandedGestureButton)
            {
                return "1) With your Main hand, move the cursor over the button." + Environment.NewLine + Environment.NewLine +
                       "2) Hold your Other hand in a relaxed fist." + Environment.NewLine + Environment.NewLine +
                       "3) With your Other hand, perform the click-gesture by extending your thumb and index finger while facing the camera.";
                //return "Keep your hand relaxed and open while moving the cursor over the button and then perform a gesture with your " + handDescriptor + " hand by closing it to a fist to activate the button.";
            }
            else if (ActiveTestType == TestMode.TwoHandedPushButton)
            {
                return "1) With your Main hand, move the cursor over the button." + Environment.NewLine + Environment.NewLine +
                       "2) With your Other hand, perform a pushing motion towards the camera to click it.";
                //return "Move the cursor over the button and then perform a pushing motion with your " + handDescriptor + " hand towards the camera to activate it.";
            }
        //    else if (ActiveTestType == TestMode.TwoHandedStickyGestureButton)
        //    {
        //        return "1) With your Main hand, move the cursor over the button to focus at it." + Environment.NewLine + Environment.NewLine +
        //               "2) Button is now focused and it can be activated from anywhere." + Environment.NewLine + Environment.NewLine +
        //               "3) Hold your Other hand in a relaxed fist." + Environment.NewLine + Environment.NewLine +
        //               "4) With your Other hand, perform the click-gesture by extending your thumb and index finger while facing the camera.";
        //// return "Keep your hand relaxed and open while moving the cursor across the button to focus at it and then perform a gesture with your " + handDescriptor + " hand by closing it to a fist to activate the button.";
        //    }
        //    else if (ActiveTestType == TestMode.TwoHandedStickyPushButton)
        //    {
        //        return "1) With your Main hand, move the cursor over the button to focus at it." + Environment.NewLine + Environment.NewLine +
        //               "2) Button is now focused and it can be activated from anywhere." + Environment.NewLine + Environment.NewLine +
        //               "3) With your Other hand, perform a pushing motion towards the camera to click it.";
        //       // return "Move the cursor across the button to focus at it and then perform a pushing motion with your " + handDescriptor + " hand towards the camera to activate it.";
        //    }

            return "Missing test type: " + ActiveTestType.ToString();
        }

        //TOD-O: Remove these
         //with your index finger and thumb pointed out,
          //else if (ActiveTestType == TestMode.PushButton)
            //{
            //    return "1) Move the cursor over the button." + Environment.NewLine + Environment.NewLine +
            //           "2) Perform a pushing motion towards the camera to click it.";
            //    //return "Move the cursor over the button and then perform a pushing motion towards the camera to activate it.";
            //}
            //else if (ActiveTestType == TestMode.StickyGestureButton)
            //{
            //    return "1) Keep your hand relaxed but closed." + Environment.NewLine + Environment.NewLine +
            //           "2) Move the cursor over the button to focus at it." + Environment.NewLine + Environment.NewLine +
            //           "3) Button is now focused and it can be activated from anywhere." + Environment.NewLine + Environment.NewLine +
            //           "4) Perform the click-gesture by briefly pointing up with your thumb and index finger while facing the camera.";

            //   // return "Keep your hand relaxed but closed while moving the cursor across the button to focus at it and then perform a gesture by briefly pointing out with your thumb and index finger to activate the button.";
            //}
         
        //    else if (ActiveTestType == TestMode.TwoHandedStickyGestureButton)
        //    {
        //        return "1) With your Main hand, move the cursor over the button to focus at it." + Environment.NewLine + Environment.NewLine +
        //               "2) Button is now focused and it can be activated from anywhere." + Environment.NewLine + Environment.NewLine +
        //               "3) Keep your Other hand relaxed and open." + Environment.NewLine + Environment.NewLine +
        //               "4) With your Other hand, perform the click-gesture by briefly closing it to a fist.";
        //// return "Keep your hand relaxed and open while moving the cursor across the button to focus at it and then perform a gesture with your " + handDescriptor + " hand by closing it to a fist to activate the button.";
        //    }
        //    else if (ActiveTestType == TestMode.TwoHandedStickyPushButton)
        //    {
        //        return "1) With your Main hand, move the cursor over the button to focus at it." + Environment.NewLine + Environment.NewLine +
        //               "2) Button is now focused and it can be activated from anywhere." + Environment.NewLine + Environment.NewLine +
        //               "3) With your Other hand, perform a pushing motion towards the camera to click it.";
        //       // return "Move the cursor across the button to focus at it and then perform a pushing motion with your " + handDescriptor + " hand towards the camera to activate it.";
        //    }

        public static string GetTestModeString(CalculatorTestMode testMode)
        {
            switch (testMode)
            {
                case CalculatorTestMode.Press1a:
                    return "Press 1";
                case CalculatorTestMode.Press1b:
                case CalculatorTestMode.Press1c:
                    return "Press 11";
                case CalculatorTestMode.Press2a:
                    return "Press 2";
                case CalculatorTestMode.Press2b:
                case CalculatorTestMode.Press2c:
                    return "Press 22";
                case CalculatorTestMode.Press3a:
                    return "Press 3";
                case CalculatorTestMode.Press3b:
                case CalculatorTestMode.Press3c:
                    return "Press 33";
                case CalculatorTestMode.Press4a:
                    return "Press 4";
                case CalculatorTestMode.Press4b:
                case CalculatorTestMode.Press4c:
                    return "Press 44";
                case CalculatorTestMode.Press5a:
                    return "Press 5";
                case CalculatorTestMode.Press5b:
                case CalculatorTestMode.Press5c:
                    return "Press 55";
                case CalculatorTestMode.Press6a:
                    return "Press 6";
                case CalculatorTestMode.Press6b:
                case CalculatorTestMode.Press6c:
                    return "Press 66";
                case CalculatorTestMode.Press7a:
                    return "Press 7";
                case CalculatorTestMode.Press7b:
                case CalculatorTestMode.Press7c:
                    return "Press 77";
                case CalculatorTestMode.Press8a:
                    return "Press 8";
                case CalculatorTestMode.Press8b:
                case CalculatorTestMode.Press8c:
                    return "Press 88";
                case CalculatorTestMode.Press9a:
                    return "Press 9";
                case CalculatorTestMode.Press9b:
                case CalculatorTestMode.Press9c:
                    return "Press 99";
            }

            /*
            if (testMode == CalculatorTestMode.EightHundredAndEightyEightMinusSevenHundredAndSeventySeven)
            {
                return "Calculate 888 minus 777 and press Ok.";
            }
            else if (testMode == CalculatorTestMode.FiveTimesSix)
            {
                return "Calculate 5 times 6 and press Ok.";
            }
            else if (testMode == CalculatorTestMode.NinePlusEightPlusSeven)
            {
                return "Calculate 9 plus 8 plus 7 and press Ok.";
            }
            else if (testMode == CalculatorTestMode.OnePlusThree)
            {
                return "Calculate 1 plus 3 and press Ok.";
            }
            else if (testMode == CalculatorTestMode.SixDividedByThree)
            {
                return "Calculate 6 divided by 3 and press Ok.";
            }
             */

            return "Unknown Test Mode! " + testMode.ToString();
        }

        public static void NextCalculation()
        {
            //all done, time for next info screen
            if (AvailableCalculations.Count == 0)
            {
                TestEnded();

                NextText();
                //AvailableCalculations = Enum.GetValues(typeof(CalculatorTestMode)).Cast<int>().OrderBy(x => random.Next()).Cast<CalculatorTestMode>().ToList();
            }
            //continue testing
            else
            {
                CalculatorMode = AvailableCalculations[0];
                AvailableCalculations.RemoveAt(0);

                try
                {
                    TestInfoControl.Info = GetTestModeString(CalculatorMode);
                }
                catch { }

                CorrectButtons.Clear();

                switch (CalculatorMode)
                {
                    case CalculatorTestMode.Press1a:
                    case CalculatorTestMode.Press1b:
                    case CalculatorTestMode.Press1c:
                        CorrectButtons.Add(CalculatorSymbol.One);
                        break;
                    case CalculatorTestMode.Press2a:
                    case CalculatorTestMode.Press2b:
                    case CalculatorTestMode.Press2c:
                        CorrectButtons.Add(CalculatorSymbol.Two);
                        break;
                    case CalculatorTestMode.Press3a:
                    case CalculatorTestMode.Press3b:
                    case CalculatorTestMode.Press3c:
                        CorrectButtons.Add(CalculatorSymbol.Three);
                        break;
                    case CalculatorTestMode.Press4a:
                    case CalculatorTestMode.Press4b:
                    case CalculatorTestMode.Press4c:
                        CorrectButtons.Add(CalculatorSymbol.Four);
                        break;
                    case CalculatorTestMode.Press5a:
                    case CalculatorTestMode.Press5b:
                    case CalculatorTestMode.Press5c:
                        CorrectButtons.Add(CalculatorSymbol.Five);
                        break;
                    case CalculatorTestMode.Press6a:
                    case CalculatorTestMode.Press6b:
                    case CalculatorTestMode.Press6c:
                        CorrectButtons.Add(CalculatorSymbol.Six);
                        break;
                    case CalculatorTestMode.Press7a:
                    case CalculatorTestMode.Press7b:
                    case CalculatorTestMode.Press7c:
                        CorrectButtons.Add(CalculatorSymbol.Seven);
                        break;
                    case CalculatorTestMode.Press8a:
                    case CalculatorTestMode.Press8b:
                    case CalculatorTestMode.Press8c:
                        CorrectButtons.Add(CalculatorSymbol.Eight);
                        break;
                    case CalculatorTestMode.Press9a:
                    case CalculatorTestMode.Press9b:
                    case CalculatorTestMode.Press9c:
                        CorrectButtons.Add(CalculatorSymbol.Nine);
                        break;
                    default:
                        break;
                }

                

                /*
                switch (CalculatorMode)
                {
                    case CalculatorTestMode.OnePlusThree:
                        CorrectButtons.Add(CalculatorSymbol.One);
                        CorrectButtons.Add(CalculatorSymbol.Add);
                        CorrectButtons.Add(CalculatorSymbol.Three);
                        break;
                    case CalculatorTestMode.FiveTimesSix:
                        CorrectButtons.Add(CalculatorSymbol.Five);
                        CorrectButtons.Add(CalculatorSymbol.Multiply);
                        CorrectButtons.Add(CalculatorSymbol.Six);
                        break;
                    case CalculatorTestMode.SixDividedByThree:
                        CorrectButtons.Add(CalculatorSymbol.Six);
                        CorrectButtons.Add(CalculatorSymbol.Divide);
                        CorrectButtons.Add(CalculatorSymbol.Three);
                        break;
                    case CalculatorTestMode.EightHundredAndEightyEightMinusSevenHundredAndSeventySeven:
                        CorrectButtons.Add(CalculatorSymbol.Eight);
                        CorrectButtons.Add(CalculatorSymbol.Eight);
                        CorrectButtons.Add(CalculatorSymbol.Eight);
                        CorrectButtons.Add(CalculatorSymbol.Substract);
                        CorrectButtons.Add(CalculatorSymbol.Seven);
                        CorrectButtons.Add(CalculatorSymbol.Seven);
                        CorrectButtons.Add(CalculatorSymbol.Seven);
                        break;
                    case CalculatorTestMode.NinePlusEightPlusSeven:
                        CorrectButtons.Add(CalculatorSymbol.Nine);
                        CorrectButtons.Add(CalculatorSymbol.Add);
                        CorrectButtons.Add(CalculatorSymbol.Eight);
                        CorrectButtons.Add(CalculatorSymbol.Add);
                        CorrectButtons.Add(CalculatorSymbol.Seven);
                        break;
                    default:
                        break;
                }
                */
            }
        }

        public static void StartTestRecording()
        {
            ActiveTest = new TestInfo(ActiveTestType);

            timer.Start();
        }

        //report every click
        public static void AddClickMarker(System.Drawing.Point point, bool hit, string button)
        {
            //info screen is over
            if (button == "Done")
            {
                //first calculation
                NextCalculation();
            }

            if (timer.IsRunning == true)
            {
                //ok is handled differently
                if (button != "Ok")
                {
                    //still something left that we should be clicking
                    if (CorrectButtons.Count > 0)
                    {
                        string correctText = CorrectButtons[0].GetDescription();
                        //right one?
                        bool rightbutton = button == correctText;

                        //right! advance
                        if (rightbutton)
                        {
                            CorrectButtons.RemoveAt(0);
                        }
                        else
                        {
                            ActiveTest.FalseClicks++;
                        }

                        ActiveTest.Clicks.Add(new ClickInfo(point, hit, timer.Elapsed, correctText, button));
                    }
                    //nothing left, false clicks
                    else
                    {
                        ActiveTest.Clicks.Add(new ClickInfo(point, hit, timer.Elapsed, "", button));

                        ActiveTest.FalseClicks++;
                    }
                }
                //save ok button info too!
                else
                {
                    ActiveTest.OkClick = new ClickInfo(point, hit, timer.Elapsed, "", button);
                }
            }
        }

        public static void OkClick(string result)
        {
            string derp = CalculatorMode.GetDescription();
            if (result == derp)
            {
                ActiveTest.SuccessfulAnswers.Add(CalculatorMode);
            }

            NextCalculation();
        }

        //call when the a single test ends
        public static void TestEnded()
        {
            timer.Stop();

            ActiveTest.Elapsed = timer.Elapsed;

            timer.Reset();

            Tests.Add(ActiveTest);
        }

        public static void StopRecording()
        {
            DataContractSerializer s = new DataContractSerializer(typeof(List<TestInfo>));

            if (Directory.Exists("C:\\Temp") == false)
            {
                Directory.CreateDirectory("C:\\Temp");
            }

            var name = "C:\\Temp\\KinectUsabilityTest-" + DateTime.Now.ToString().Replace(':', '.') + ".dat";

            if (File.Exists(name) == false)
            {
                var stream = File.Create(name);
                s.WriteObject(stream, Tests);
            }
            //dat dat!
            else
            {
                var stream = File.Create(name + ".dat");
                s.WriteObject(stream, Tests);
            }

            //foreach (System.Windows.Window item in App.Current.Windows)
            //{
            //    item.Close();
            //}

        }
    }
}
